// Copyright (C) 2005 Taylor L. Riché <riche@cs.utexas.edu>
//  
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software 
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// 	$Id: ApplicationGraph.cc 83 2005-08-02 17:19:18Z richetl $	
//

#include "ApplicationGraph.hh"

using namespace lee;

PPFunction * 
ApplicationGraph::getNextPPFunction(std::string ppfName, int exitPoint) 
{
  Synchronized::Scope mutex(this);
  std::map<int, PPFunction *> * target;
  while((target = appGraph[ppfName]) == NULL) {
    wait();
  }
  return (*target)[exitPoint];
}

void
ApplicationGraph::makeConnection(std::string leftPpf, int leftPort, std::string rightPpf)
{
  Synchronized::Scope mutex(this);
  if(appGraph[rightPpf] == NULL) {
    appGraph[rightPpf] = new std::map<int, PPFunction*>;
  }
  while(ppfMap[rightPpf] == NULL) {
    wait();
  }
  assert(appGraph[leftPpf] != NULL);
  (*appGraph[leftPpf])[leftPort] = ppfMap[rightPpf];
  notify();
  return;
}

// The following three methods will only be necessary once dynamic
// changes to the application graph are enabled with event handlers

void 
ApplicationGraph::addPpfAfter(std::string origPpf, int origPort, 
			      std::string newPpf, int newPort)
{
  Synchronized::Scope mutex(this);

  if(appGraph[newPpf] == NULL) {
    appGraph[newPpf] = new std::map<int, PPFunction*>;
  }
  PPFunction * oldPpf = (*appGraph[origPpf])[origPort];
  (*appGraph[newPpf])[newPort] = oldPpf;
  while(ppfMap[newPpf] == NULL) {
    wait();
  }
  (*appGraph[origPpf])[origPort] = ppfMap[newPpf];
  notify();
  return;
}

void 
ApplicationGraph::addPpfBefore(std::string newPpf, int newPort, std::string origPpf)
{
  Synchronized::Scope mutex(this);
  notify();
  return;
}

void
ApplicationGraph::deletePPFunction(std::string ppfName)
{
  Synchronized::Scope mutex(this);
  notify();
  return;
}
